#include "Thread.hpp"
#include <string>
#include <iostream>
#include <vector>
#include <unistd.h>
#include "LockGuard.hpp"
const int gnum = 5;
std::string GetThreadName()
{
    static int gcount = 1;
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "thread-%d", gcount++);
    return buffer;
}

void Print(int num)
{
    while (num--)
    {
        std::cout << "hello linux!!" << std::endl;
        sleep(1);
    }
}

class ThreadDate
{
public:
    ThreadDate(std::string _name, pthread_mutex_t *_mutex)
        : name(_name), pmutex(_mutex)
    {
    }
    pthread_mutex_t *pmutex;
    std::string name;
    ~ThreadDate()
    {
    }
};

int ticket = 1000;
void GetTicket(ThreadDate *td)
{
    while (true)
    {
        {
            LockGuard lockguard(td->pmutex);
            if (ticket > 0)
            {
                usleep(1000);
                printf("%s,get a ticket: %d\n", td->name.c_str(), ticket);
                --ticket;
            }
            else
            {
                break;
            }
        }
    }
}

// int main()
// {
//     Thread t(GetThreadName(), Print);
//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;
//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;
//     t.Start();

//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;
//     t.Join();
//     return 0;
// }

// 完成单线程版本，下一步实现多线程，实现带参数

// int main(){
//     const int num = 5;
//     std::vector<Thread> threads;
//     threads.reserve(5);
//     for (int i = 0; i < num; i++)
//     {
//         threads.push_back(Thread(GetThreadName(),Print));
//         threads[i].Start();
//     }

//     for (auto &t : threads)
//     {
//         std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;
//     }

//     for (auto &t : threads)
//     {
//         t.Join();
//     }
//     return 0;
// }

// int main()
// {
//     Thread<int> t(GetThreadName(), Print, 10);
//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;
//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;
//     t.Start();

//     std::cout << t.ThreadName() << ",isrunning:" << t.IsRunning() << std::endl;

//     t.Join();

//     return 0;
// }

/************
 *     模拟抢票功能
 ************ */
//////////////////   V1
// int main()
// {
//     std::string name1 = GetThreadName();
//     Thread<std::string> t1(name1, GetTicket, name1);

//     std::string name2 = GetThreadName();
//     Thread<std::string> t2(name2, GetTicket, name2);

//     std::string name3 = GetThreadName();
//     Thread<std::string> t3(name3, GetTicket, name3);

//     std::string name4 = GetThreadName();
//     Thread<std::string> t4(name4, GetTicket, name4);

//     t1.Start();
//     t2.Start();
//     t3.Start();
//     t4.Start();

//     t1.Join();
//     t2.Join();
//     t3.Join();
//     t4.Join();

//     return 0;
// }

//////////////////   V2

int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);

    std::string name1 = GetThreadName();
    ThreadDate *d1 = new ThreadDate(name1, &mutex);
    Thread<ThreadDate *> t1(name1, GetTicket, d1);

    std::string name2 = GetThreadName();
    ThreadDate *d2 = new ThreadDate(name2, &mutex);
    Thread<ThreadDate *> t2(name2, GetTicket, d2);

    std::string name3 = GetThreadName();
    ThreadDate *d3 = new ThreadDate(name3, &mutex);
    Thread<ThreadDate *> t3(name3, GetTicket, d3);

    std::string name4 = GetThreadName();
    ThreadDate *d4 = new ThreadDate(name4, &mutex);
    Thread<ThreadDate *> t4(name4, GetTicket, d4);

    t1.Start();
    t2.Start();
    t3.Start();
    t4.Start();

    t1.Join();
    t2.Join();
    t3.Join();
    t4.Join();

    return 0;
}